<template>
  <div :class="['b-table',{'b-height':comPaginationIsShow}]">
    <div class="toolbar"
         v-if="comToolbarIsShow">
      <div class="toolbar_export">
        <div v-for="item in comExportList"
             :key="item.name"
             class="toolbar_export_item"
             @click="handleExport(item.name)">
          <img src="./icon/doc_csv.png"
               v-if="item.icon==='doc_csv.png'"
               class="toolbar_export_item_icon">
          <img src="./icon/doc_pdf.png"
               v-if="item.icon==='doc_pdf.png'"
               class="toolbar_export_item_icon">
          <img src="./icon/doc_excel.png"
               v-if="item.icon==='doc_excel.png'"
               class="toolbar_export_item_icon">
          <span class="toolbar_export_item_text">{{ item.name }}</span>
        </div>
      </div>
      <el-popover v-if="comColumnsIsShow"
                  placement="bottom-end"
                  width="250"
                  trigger="click"
                  ref="columnPop">
        <div class="toolbar_columns"
             slot="reference">
          <span class="toolbar_columns_text">
            {{$t('custom.widget.grid.columns')}}
          </span>
          <i class="el-icon-caret-bottom"></i>
        </div>
        <div class="toolbar_columnsPop">
          <div class="toolbar_columnsPop_title">{{$t('custom.widget.grid.chooseColumn')}}</div>
          <div class="toolbar_columnsPop_content">
            <el-input :placeholder="$t('custom.widget.grid.search')"
                      v-model="columnKey"
                      class="toolbar_columnsPop_content_search">
              <el-button slot="append"
                         icon="el-icon-search"></el-button>
            </el-input>
            <div class="toolbar_columnsPop_content_list">
              <el-checkbox v-show="comSearchColumns.length"
                           class="toolbar_columnsPop_content_list_item"
                           :indeterminate="isIndeterminate"
                           v-model="checkAll"
                           @change="handleCheckAllChange">{{$t('custom.widget.grid.selectAll')}}</el-checkbox>
              <el-checkbox-group v-model="checkedColumns"
                                 @change="handleCheckedColumnsChange">
                <el-checkbox class="toolbar_columnsPop_content_list_item"
                             v-for="(column, index) in comSearchColumns"
                             :label="column.field"
                             :key="index">{{ column.field
                  }}</el-checkbox>
              </el-checkbox-group>
            </div>
          </div>
          <div class="toolbar_columnsPop_footer">
            <el-button type="primary"
                       size="mini"
                       class="toolbar_columnsPop_footer_ok"
                       @click="handleBtn(true)">{{$t('custom.widget.grid.ok')}}</el-button>
            <el-button type="info"
                       size="mini"
                       class="toolbar_columnsPop_footer_cancel"
                       @click="handleBtn(false)">{{$t('custom.widget.grid.cancel')}}</el-button>
          </div>
        </div>
      </el-popover>
    </div>
    <el-table :key="checkedColumnsOK.length"
              class="myTable"
              ref="tableRef"
              border
              :cell-style="handleCellStyle"
              :row-style="handleRowStyle"
              :header-cell-style="{ background: '#f5f7fa' }"
              :data="autoFull||pageFromType==='reportLayoutGrid'?comReportList:comPaginationIsShow ? comTableData : showList"
              style="width: 100%;"
              v-bind="$attrs"
              v-on="$listeners"
              :height="comTableHeight"
             >
      <slot name="selection"></slot>
      <slot name="index"></slot>
      <slot v-for="column in comColumns"
            :name="column.field"></slot>
      <slot name="tableAction"></slot>
    </el-table>
    <!-- <div class="pagination"
         v-if="comPaginationIsShow&&!autoFull">
      <el-pagination @size-change="handleSizeChange"
                     @current-change="handleCurrentChange"
                     :current-page="pageSettings.pageCount"
                     :page-sizes="pageSettings.pageSizes"
                     :page-size="pageSettings.pageSize"
                     layout="total, sizes, prev, pager, next, jumper"
                     :total="comTotal">
      </el-pagination>
    </div> -->
  </div>
</template>

<script>
import { throttle } from 'lodash'
import moment from 'moment'
export default {
  name: 'BTable',
  props: {
    columns: Array,
    tableData: Array,
    gadgetSetting: Object,
    pageConfig: Object,
    gadgetHeight: [String, Number],
    startIndex: [String, Number],
    endIndex: [String, Number],
    conditionFormat: Array,
    autoFull: Boolean,
    pageFromType: String,
    dataFrom: String,
    gadgetFontSize: [String, Number],
  },
  data () {
    return {
      columnKey: null,
      isIndeterminate: false,
      checkAll: true,
      checkedColumns: [],
      checkedColumnsOK: [],
      showList: [],
      tableRef: null,
      tableWarp: null,
      scrollTop: 0,
      num: 0,
      start: 0,
      end: 63,
      starts: 0,
      ends: 63,
      pageList: 21,
      itemHeight: 24,
      timeOut: 400,
      pageSetting: {
        "pageSize": 50,
        "pageCount": 1,
        "pageSizes": [
          50,
          100,
          500,
          1000
        ]
      }
    }
  },
  computed: {
    pageSettings () {
      return this.dataForm==='grid'?{
        "pageSize": this.pageConfig.pageSize,
        "pageCount": this.pageConfig.current,
        "pageSizes": this.gadgetSetting.report.pageSettings.pageSizes
      }:this.pageSetting
    },
    comTotal () {
      return this.tableData.length || 0
    },
    comTableData () {
      return this.tableData
    },
    comReportList () {
      return this.pageFromType==='reportLayoutGrid'?this.tableData:this.tableData.slice(this.startIndex, this.endIndex + 1)
    },
    comColumns () {
      return this.columns.filter(v => this.checkedColumnsOK.includes(v.field))
    },
    comExportList () {
      let exportList = [
        { icon: 'doc_pdf.png', name: 'PDF Export', key: 'PdfExport' },
        { icon: 'doc_csv.png', name: 'CSV Export', key: 'CsvExport' },
        // { icon: 'doc_excel.png', name: 'Excel Export', key: 'ExcelExport' },
      ]
      return this.gadgetSetting.report.allowGrouping ? exportList.filter(v => this.gadgetSetting.report.toolbar.includes(v.key)) : []
    },
    comColumnsIsShow () {
      return this.gadgetSetting.report.allowGrouping && this.gadgetSetting.report.toolbar.includes('ColumnChooser')
    },
    comToolbarIsShow () {
      return this.gadgetSetting.report.allowGrouping && this.gadgetSetting.report.toolbar.length
    },
    comPaginationIsShow () {
      return this.gadgetSetting.report && (this.gadgetSetting.report.allowPaging || (this.gadgetSetting.report.gridStyle === 'List' && this.$route.path !== '/publicReportPdf'))
    },
    comTableHeight () {
      let height = 80
      if (!this.comToolbarIsShow) height += 10
      if (!this.comPaginationIsShow) height += 10
      return height + '%'
    },
    comCloneColumns () {
      return this.columns.map(v => v.field)
    },
    comSearchColumns () {
      return this.columns.filter(v => !this.columnKey || v.field.toLowerCase().includes(this.columnKey.toLowerCase()))
    }
  },
  watch: {
    num: function (newV) {
      if (newV > 1) {
        this.start = (newV - 1) * this.pageList
        this.end = (newV + 2) * this.pageList
        requestAnimationFrame(() => {
          this.tableWarp.style.transform = `translateY(${this.start *
            this.itemHeight}px)`
          this.showList = this.comTableData.slice(this.start, this.end)
        })
      } else {
        requestAnimationFrame(() => {
          this.showList = this.comTableData.slice(this.starts, this.ends)
          this.tableWarp.style.transform = `translateY(0px)`
        })
      }
    }
  },
  created () {
    this.checkedColumns = [...this.comCloneColumns]
    this.checkedColumnsOK = [...this.checkedColumns]
    if (this.comPaginationIsShow || this.autoFull) return
    this.pageList = Math.ceil((this.gadgetHeight) / this.itemHeight)
    this.end = this.ends = this.pageList * 3
    this.pageSettings.pageSize = this.tableData.length
    this.showList = this.comTableData.slice(this.start, this.end)
  },
  mounted () {
    if (this.comPaginationIsShow || this.autoFull) return
    this.$nextTick(() => {
      const rowList= this.$refs.tableRef.$el.querySelectorAll('.el-table__row')
      if(rowList){
        let count=0
        rowList.forEach(v=>{
          count+=parseInt(v.offsetHeight)
        })
        this.itemHeight=Math.ceil(count/rowList.length)
        this.pageList = Math.ceil((this.gadgetHeight) / this.itemHeight)
        this.end = this.ends = this.pageList * 3
        this.showList = this.comTableData.slice(this.start, this.end)
      }
      this.tableRef = this.$refs.tableRef.bodyWrapper
      let divWarpPar = document.createElement('div')
      divWarpPar.style.height = this.comTableData.length * this.itemHeight + 'px'
      let divWarpChild = document.createElement('div')
      divWarpChild.className = 'fix-warp'
      divWarpChild.append(this.tableRef.children[0])
      divWarpPar.append(divWarpChild)
      this.tableRef.append(divWarpPar)
      this.tableWarp = document.querySelector(
        '.el-table .el-table__body-wrapper .fix-warp'
      )
      this.tableRef.addEventListener('scroll', throttle(this.onScroll, 300))
    })
  },
  methods: {
    handleSizeChange (v) {
      this.pageSetting.pageSize = v
    },
    handleCurrentChange (v) {
      this.pageSetting.pageCount = v
    },
    onScroll () {
      this.scrollTop = this.tableRef.scrollTop
      this.num = Math.floor(this.scrollTop / (this.itemHeight * this.pageList))
    },
    handleExport (key) {
      this.$emit('handleTableExport', key)
    },
    handleCheckAllChange (val) {
      this.checkedColumns = val ? this.comCloneColumns : [];
      this.isIndeterminate = false;
    },
    handleCheckedColumnsChange (value) {
      let checkedCount = value.length;
      this.checkAll = checkedCount === this.comCloneColumns.length;
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.comCloneColumns.length;
    },
    handleBtn (type) {
      if (type) {
        this.checkedColumnsOK = [...this.checkedColumns]
      }
      this.$refs.columnPop.doClose()
    },
    handleRowStyle (args) {
      try {
        let rowIndex
        let stylejson = {}
        var res = this.conditionFormat
        if (args.row) {
          res.forEach(it => {
            if (it) {
              let str = ''
              it.dataForm.filters.rules.forEach(ii => {
                if (ii.opt === 'is null'  ) {
                   ii.value = 'is null'
                   ii.opt = '=='
                }
                var val = args.row[ii.key] === null? 'is null' : args.row[ii.key] ? args.row[ii.key].toString() : ''
                if (ii.type === 'date' || ii.type === 'datetime') {
                  val = moment(val).format("YYYY-MM-DD")
                  let dateRange = ii.valueList && Array.isArray(ii.valueList) ? ii.valueList : []
                  if (dateRange.length) {
                    let operator = it.dataForm.filters.condition === 'and' ? '&&' : '||'
                    if (dateRange.length === 1) {
                      if (dateRange[0].startTime === dateRange[0].endTime) {
                        str += (!str ? '' : operator) + `('${val}' ${ii.opt} '${dateRange[0].startTime}')`
                      } else {
                        if (ii.opt === '==') {
                          str += (!str ? '' : operator) + `('${val}' >= '${dateRange[0].startTime}' && '${val}' <= '${dateRange[0].endTime}')`
                        }
                        if (ii.opt === '!=') {
                          str += (!str ? '' : operator) + `('${val}' < '${dateRange[0].startTime}' || '${val}' > '${dateRange[0].endTime}')`
                        }
                        if (ii.opt === '>') {
                          str += (!str ? '' : operator) + `('${val}' > '${dateRange[0].endTime}')`
                        }
                        if (ii.opt === '>=') {
                          str += (!str ? '' : operator) + `!('${val}' < '${dateRange[0].startTime}')`
                        }
                        if (ii.opt === '<') {
                          str += (!str ? '' : operator) + `('${val}' < '${dateRange[0].startTime}')`
                        }
                        if (ii.opt === '<=') {
                          str += (!str ? '' : operator) + `!('${val}' > '${dateRange[0].endTime}')`
                        }
                      }
                    } else if (ii.opt === '==' || ii.opt === '!=') {
                      let result = ''
                      if (ii.opt === '==') {
                        dateRange.forEach(v => {
                          result += `('${val}' >= '${v.startTime}' && '${val}' <= '${v.endTime}')||`
                        })
                      } else {
                        dateRange.forEach(v => {
                          result += `('${val}' < '${v.startTime}' || '${val}' > '${v.endTime}')&&`
                        })
                      }
                      if (result.substr(-2) === '||' || result.substr(-2) === '&&') {
                        result = result.substr(0, result.length - 2)
                      }
                      str += (!str ? '' : operator) + result
                    } else if (ii.opt === '>') {
                      str += (!str ? '' : operator) + `('${val}' > '${dateRange[dateRange.length - 1].endTime}')`
                    } else if (ii.opt === '>=') {
                      str += (!str ? '' : operator) + `!('${val}' < '${dateRange[0].startTime}')`
                    } else if (ii.opt === '<') {
                      str += (!str ? '' : operator) + `('${val}' < '${dateRange[0].startTime}')`
                    } else if (ii.opt === '<=') {
                      str += (!str ? '' : operator) + `!('${val}' > '${dateRange[dateRange.length - 1].endTime}')`
                    }
                  }
                } else {
                  if (ii.opt === '==' || ii.opt === '!=') {
                    if (!str) {
                      str += `("${(val).toString()}"  ${ii.opt}   "${(ii.value).toString()}")`
                    } else {
                      if (it.dataForm.filters.condition === 'and') {
                        str += `&& ("${(val).toString()}"  ${ii.opt}   "${(ii.value).toString()}")`
                      } else {
                        str += `|| ("${(val).toString()}"   ${ii.opt}   "${(ii.value).toString()}")`
                      }
                    }
                  } else {
                    if (!str) {
                      str += (Number(val) + ii.opt + Number(ii.value))
                    } else {
                      if (it.dataForm.filters.condition === 'and') {
                        str += `&& (${Number(val)}   ${ii.opt}   ${Number(ii.value)})`
                      } else {
                        str += `|| (${Number(val)}   ${ii.opt}   ${Number(ii.value)})`
                      }
                    }
                  }
                }
              })
              let res1 = eval(`${str}`)
              if (res1) {
                if (it.entireRow === 'row') {
                  rowIndex = args.rowIndex
                  stylejson.color = it.textColor
                  stylejson.backgroundColor = it.backgroundColor
                }
              }
            }
          })
          stylejson.padding = '0'
          if (this.gadgetFontSize) {
            stylejson.fontSize = `${this.gadgetFontSize}px`
          }
          if (args.rowIndex === rowIndex) {
            return stylejson
          }
          return stylejson
        }
      } catch (error) {
        console.log(error);
      }

    },
    handleCellStyle (args) {
      try {
        let rowIndex
        let color
        let bgc
        var res = this.conditionFormat
        if (args.row) {
          res.forEach(it => {
            if (it) {
              let str = ''
              it.dataForm.filters.rules.forEach(ii => {
                if (ii.opt === 'is null'  ) {
                   ii.value = 'is null'
                   ii.opt = '=='
                }
                let val
                if (args.column.property === ii.key) {
                  if (args.column.property === ii.key) {
                    val = args.row[ii.key] ===null ? 'is null' : args.row[ii.key] ? args.row[ii.key].toString() : ''
                  } else {
                    val = ''
                  }
                  if (ii.opt === '==' || ii.opt === '!=') {
                    if (!str) {
                      str += `("${(val).toString()}"  ${ii.opt}   "${(ii.value).toString()}")`
                    } else {
                      if (it.dataForm.filters.condition === 'and') {
                        str += `&& ("${(val).toString()}"  ${ii.opt}   "${(ii.value).toString()}")`
                      } else {
                        str += `|| ("${(val).toString()}"   ${ii.opt}   "${(ii.value).toString()}")`
                      }
                    }
                  } else {
                    if (!str) {
                      str += (Number(val) + ii.opt + Number(ii.value))
                    } else {
                      if (it.dataForm.filters.condition === 'and') {
                        str += `&& (${Number(val)}   ${ii.opt}   ${Number(ii.value)})`
                      } else {
                        str += `|| (${Number(val)}   ${ii.opt}   ${Number(ii.value)})`
                      }
                    }
                  }
                }
              })
              let res1 = eval(`${str}`)
              if (res1) {
                if (it.entireRow !== 'row') {
                  rowIndex = args.rowIndex
                  color = it.textColor
                  if (it.formatRadio === 'color' || (it.backgroundColor && !(it.hasOwnProperty('formatRadio')))) {
                    bgc = it.backgroundColor
                  }
                  if (it.formatRadio === 'icon') {
                    args.row[args.column.property] = it.icon
                  }
                }
              }
            }
          })
          if (args.rowIndex === rowIndex) {
            return `backgroundColor: ${bgc};color:${color};padding:0`
          }
          return `padding:0`
        }

      } catch (error) {
        console.log(error);
      }

    }
  }
}
</script>

<style lang="scss" scoped>
.myTable {
  /deep/ td {
    // padding: 6px 0 !important;
  }
  /deep/ .el-table__body-wrapper{
    // height: 100%!important;
  }
}
/deep/ .el-table .cell{
  word-break: break-word !important;
  line-height: normal !important;
}

///deep/ .el-table__body-wrapper::-webkit-scrollbar {
//  width: 6px;
//  height: 8px;
//}
//
// /deep/ .cell{
//   max-height: 35px !important;
//   overflow: hidden !important;
// }
//
///deep/ .el-table__body-wrapper::-webkit-scrollbar-thumb {
//  border-radius: 2px;
//  background: #666;
//}
//
///deep/ .el-table__body-wrapper::-webkit-scrollbar-track {
//  background: #ccc;
//}
.b-height {
  height: calc(100% - 50px)!important;
}
.b-table {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  .toolbar {
    height: 40px;
    background: #f5f5f5;
    padding: 0 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;

    &_export {
      display: flex;
      align-items: center;
      justify-content: space-between;

      &_item {
        margin-right: 20px;
        height: 40px;
        display: flex;
        align-items: center;
        padding: 0 5px;
        user-select: none;
        cursor: pointer;
        &_icon {
          width: 22px;
          height: 22px;
        }
        &_text {
          margin-left: 5px;
        }

        &:hover {
          background: #ccc;
        }
      }
    }

    &_columns {
      display: flex;
      align-items: center;
      user-select: none;
      cursor: pointer;

      &_text {
        margin-right: 5px;
      }

      height: 40px;
      line-height: 40px;
      padding: 0 5px;

      &:hover {
        background: #ccc;
      }
    }
  }

  .pagination {
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: end
  }
}
/deep/ .toolbar_columnsPop {
  &_title {
    border-bottom: 1px solid #eee;
    font-size: 16px;
    font-weight: bold;
    padding-bottom: 10px;
  }

  &_content {
    &_search {
      padding: 5px 0;
    }

    &_list {
      height: 150px;
      padding: 10px 0;
      overflow-y: scroll;
      overflow-x: hidden;

      &_item {
        padding: 5px;
        display: block;
      }
    }
  }

  &_footer {
    border-top: 1px solid #eee;
    display: flex;
    justify-content: flex-end;
    padding-top: 10px;

    &_ok {
      margin-right: 5px;
    }
  }
}
</style>
